package com.orange.adminapi.service.permission;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.orange.core.mapper.permission.RoleMapper;
import com.orange.core.pojo.entity.permission.Permission;
import com.orange.core.pojo.entity.permission.Role;
import com.orange.core.pojo.entity.permission.RolePermission;
import com.orange.core.pojo.enums.EPermission;
import com.orange.core.pojo.enums.ERole;
import com.orange.core.pojo.enums.EStatus;
import lombok.AllArgsConstructor;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@AllArgsConstructor
@Service
public class RoleService extends ServiceImpl<RoleMapper, Role> {

    private final RolePermissionService rolePermissionService;

    public List<Role> list() {
        return this.lambdaQuery().orderByDesc(Role::getCreateTime).list();
    }

    /**
     * 获取有效角色
     */
    public List<Role> validList(@Nullable Set<Integer> roleIds) {
        return this.list(new LambdaQueryWrapper<Role>().in(CollUtil.isNotEmpty(roleIds), Role::getId, roleIds).eq(Role::getStatus, EStatus.NORMAL.getValue()));
    }

    public Role detail(Role role) {
        if (role != null) {
            role.setPermissionIds(rolePermissionService.lambdaQuery()
                    .eq(RolePermission::getRoleId, role.getId())
                    .list().stream().map(RolePermission::getPermissionId).distinct().collect(Collectors.toList()));
        }
        return role;
    }

    @Transactional
    @Override
    public boolean save(Role role) {
        super.save(role);
        if (CollUtil.isNotEmpty(role.getPermissionIds())) {
            List<RolePermission> rolePermissions = role.getPermissionIds().stream().map(pId -> new RolePermission(role.getId(), pId)).collect(Collectors.toList());
            rolePermissionService.saveBatch(rolePermissions);
        }
        return true;
    }

    @Transactional
    public boolean update(Role role) {
        super.updateById(role);
        rolePermissionService.remove(new LambdaQueryWrapper<RolePermission>().eq(RolePermission::getRoleId, role.getId()));
        if (CollUtil.isNotEmpty(role.getPermissionIds())) {
            List<RolePermission> rolePermissions = role.getPermissionIds().stream().map(pId -> new RolePermission(role.getId(), pId)).collect(Collectors.toList());
            rolePermissionService.saveBatch(rolePermissions);
        }
        return true;
    }

    @Transactional
    public boolean setStatus(int id, EStatus status) {
        if (status != null) {
            Role role = this.getById(id);
            if (!role.getCode().equalsIgnoreCase(ERole.ADMIN.getCode())) {
                return this.updateById(new Role().setId(id).setStatus(status.getValue()));
            }
        }
        return false;
    }

    public List<Permission> permissionTree() {
        return EPermission.getPermissionTree();
    }
}
